/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package spoc.classes;

import java.io.File;
import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

import spoc.classes.CPF;
import spoc.classes.Cliente;

/**
 *
 * @author dolalima
 */
public abstract class BancoDeDados {
    
    private static String rootDir = System.getProperty("user.dir"); 

    private static String urlDataBase = System.getProperty("file.separator")+"db"+
            System.getProperty("file.separator")+"spoc.db";
    private static boolean connectionStatus = false;
    private static boolean fileStatus = false;
    private static Connection connection;
    
    
    private static void CreateDbFile(){
        boolean exists = (new File(rootDir+urlDataBase)).exists();
        if (!exists) {
            System.out.print("O arquivo do banco de dados não existe,\n"+
                    "o sistema tetanra criara e configura o arquivo.\n");
            File dir = new File(rootDir+System.clearProperty("file.separator")+
                    "db"+System.clearProperty("file.separator"));
            if (dir.mkdir()) {
                System.out.println("Diretorio criado com sucesso!");
                File dbFile =new File(rootDir+urlDataBase);
            System.out.print("Arquivo criado com sucesso.\n");
            } else {  
                System.out.println("Erro ao criar diretorio!");
                File dbFile =new File(rootDir+urlDataBase);
            }
            
            
        }else{
            fileStatus = true;
            System.out.print("O arquivo de banco de dados já exite.\n"+
                    "O sistema ira se conecta ao banco de dados ja existente.\n");
        }
    }
    public static void Connect() throws ClassNotFoundException {
        CreateDbFile();
        DbConstructor();       
        Class.forName("org.sqlite.JDBC");
        try {
            connection = DriverManager.getConnection("jdbc:sqlite:"+rootDir+urlDataBase);
            connectionStatus = true;
            System.out.println("Sistema Conectado ao Bando de Dados.");
        } catch (SQLException ex) {
            System.out.println("Falha ao conecta no Bando de Dados.");
            Logger.getLogger(BancoDeDados.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        
            
        
    }
    
    public static void Disconnect(){
        try {
            connection.close();
        } catch (SQLException ex) {
            Logger.getLogger(BancoDeDados.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
        
    private static void DbConstructor(){
        try {
            System.out.print("O sistema ira iniciar a constroção das tabela de dados.\n");
            Class.forName("org.sqlite.JDBC");
            connection = DriverManager.getConnection("jdbc:sqlite:"+rootDir+urlDataBase);
            Statement statement = connection.createStatement();
            statement.executeUpdate("CREATE TABLE IF NOT EXISTS cliente ("
                    + "`codigo` int(9) NOT NULL,"
                    + "`nome` varchar(80) NOT NULL,"
                    + "`sexo` varchar(1) NOT NULL,"
                    + "`cpf` varchar(14) NOT NULL,"
                    + "`rg` bigint(20) NOT NULL,"
                    + "`rua` varchar(70) NOT NULL,"
                    + "`ncasa` int(5) NOT NULL,"
                    + "`bairro` varchar(30) NOT NULL,"
                    + "`cidade` varchar(30) NOT NULL,"
                    + "`complemento` varchar(30) NOT NULL,"
                    + "`uf` varchar(2) NOT NULL,"
                    + "`email` varchar(70) NOT NULL,"
                    + "`telefone` varchar(13) NOT NULL,"
                    + "`celular` varchar(13) NOT NULL,"
                    + "`cep` varchar(9) NOT NULL,"
                    + "`info` varchar(400) NOT NULL,"
                    + "`ativo` tinyint(1) NOT NULL DEFAULT '1',"
                    + "PRIMARY KEY (`codigo`))");
            System.out.print(">> Tabela Cliente criada com sucesso.\n");
            statement.executeUpdate("CREATE TABLE IF NOT EXISTS `material` ("
                    + "`codigo` int(11) NOT NULL,"
                    + "`nome` varchar(75) NOT NULL,"
                    + "`preco` double NOT NULL,"
                    + "`info` varchar(400) NOT NULL,"
                    + "PRIMARY KEY (`codigo`))");
            System.out.print(">> Tabela Material criada com sucesso.\n");
            statement.executeUpdate("CREATE TABLE IF NOT EXISTS `item_cortina` ("
                    + "`id_material` INT NOT NULL ,"
                    + "`id_cortina` INT NOT NULL ,"
                    + "`coef` DOUBLE NOT NULL"
                    + ")");
            System.out.print(">> Tabela Item de Cortina criada com sucesso.\n");
            statement.executeUpdate("CREATE TABLE IF NOT EXISTS `cortina` ("
                    + "`codigo` INT NOT NULL ,"
                    + "`nome` VARCHAR( 75 ) NOT NULL ,"
                    + "`info` VARCHAR( 400 ) NOT NULL,"
                    + "PRIMARY KEY (`codigo`))");
            System.out.print(">> Tabela Cortina criada com sucesso.\n");
            
            connection.close();
            System.out.println(">> Banco de dados verificado.");
        } catch (Exception ex) {
            Logger.getLogger(BancoDeDados.class.getName()).log(Level.SEVERE, null, ex);
        }
        
    }
    
     
    

    public static boolean existeCPF(CPF cpf) {
        PreparedStatement preparedStatement;
        ResultSet resultset;
        try {
            preparedStatement = connection.prepareStatement("SELECT `cpf` FROM "
                    + "`cliente` WHERE cpf=?");
            preparedStatement.setString(1, cpf.toString());
            resultset = preparedStatement.executeQuery();

            if (resultset.next()) {
                return true;
            } else {
                return false;
            }

        } catch (SQLException e) {
            e.printStackTrace();
            return false;
        }
    }

    public static boolean cadastrar(Cliente cliente) {
        PreparedStatement preparedStatement;
        ResultSet resultset;
        try {
            // Configuração de pre-comando
            preparedStatement = connection.prepareStatement("INSERT INTO cliente(codigo,nome,"
                    + "sexo,cpf,rg,rua,ncasa,bairro,cidade,complemento,uf,email,telefone,"
                    + "celular,cep,info) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
            // Entrada de valores
            preparedStatement.setString(1,"(SELECT max(a) FROM t1)+1");
            preparedStatement.setString(2, cliente.getNome());
            preparedStatement.setString(3, String.valueOf(cliente.getSexo()));
            preparedStatement.setString(4, cliente.getCpf().toString());
            preparedStatement.setLong(5, cliente.getRg());
            preparedStatement.setString(6, cliente.getEndereco().getRua());
            preparedStatement.setInt(7, cliente.getEndereco().getNum());
            preparedStatement.setString(8, cliente.getEndereco().getBairro());
            preparedStatement.setString(9, cliente.getEndereco().getCidade());
            preparedStatement.setString(10, cliente.getEndereco().getComplemento());
            preparedStatement.setString(11, cliente.getEndereco().getUf());
            preparedStatement.setString(12, cliente.getEmail());
            preparedStatement.setString(13, cliente.getTelefone());
            preparedStatement.setString(14, cliente.getCelular());
            preparedStatement.setString(15, cliente.getEndereco().getCep());
            preparedStatement.setString(16, cliente.getInformacoes());
            //Execução de comando
                        
            return true;

        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("Erro no cadastro de Cliente");
            return false;
        }
    }
    
    public static boolean cadastrar(Material material) {
        PreparedStatement preparedStatement;
        ResultSet resultset;
        try {
            // Configuração de pre-comando
            preparedStatement = connection.prepareStatement("INSERT INTO produtos "
                    + "(codigo,nome,qt,preco_custo,preco_venda,info) VALUES (?,?,?,?,?,?)");
            //Entrada de valores
            preparedStatement.setLong(1, material.getCodigo());
            preparedStatement.setString(2, material.getNome());
            preparedStatement.setDouble(3, material.getPreco());
            preparedStatement.setString(4, material.getInformacao());
            // Executando comando SQL
            preparedStatement.executeUpdate();
            //
            return true;


        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("Erro ao cadastra material.");
            return false;
        }

    }
    
    public static boolean cadastrar(Cortina cortina){
        return false;
    }
    
    

    public static boolean alterar(Cliente cliente) {
        try {
            // Preparação de commando SQL para atualização de registros
            PreparedStatement prepared = connection.prepareStatement("UPDATE cliente SET "
                    + "nome=?,sexo=?,cpf=?,rg=?,rua=?,ncasa=?,bairro=?,cidade=?"
                    + ",complemento=?,uf=?,email=?,telefone=?,celular=?,cep=?,info=? "
                    + "WHERE codigo=?");
            // introdução das variaveis no comando
            prepared.setString(1, cliente.getNome());
            prepared.setString(2, String.valueOf(cliente.getSexo()));
            prepared.setString(3, cliente.getCpf().toString());
            prepared.setLong(4, cliente.getRg());
            prepared.setString(5, cliente.getEndereco().getRua());
            prepared.setInt(6, cliente.getEndereco().getNum());
            prepared.setString(7, cliente.getEndereco().getBairro());
            prepared.setString(8, cliente.getEndereco().getCidade());
            prepared.setString(9, cliente.getEndereco().getComplemento());
            prepared.setString(10, cliente.getEndereco().getUf());
            prepared.setString(11, cliente.getEmail());
            prepared.setString(12, cliente.getTelefone());
            prepared.setString(13, cliente.getCelular());
            prepared.setString(14, cliente.getEndereco().getCep());
            prepared.setString(15, cliente.getInformacoes());
            // Codigo do cliente que ira ser alterado
            prepared.setLong(16, cliente.getCodigo());
            //Executa alteraçõe no banco de dados
            prepared.executeUpdate();

            return true;

        } catch (SQLException e) {
            e.printStackTrace();
            return false;
        }
        
    }
    
    
    public static boolean alterar(Material material) {
        try {
            // Configuração de pre-comando
            
            PreparedStatement prepared = connection.prepareStatement("UPDATE produtos SET "
                    + "nome=?,preco=?,info=? "
                    + "WHERE codigo=?");
            //Entrada de valores
            prepared.setString(1, material.getNome());
            prepared.setDouble(2, material.getPreco());
            prepared.setString(5, material.getInformacao());
            // Codico do produto que ira ser alterado
            prepared.setLong(6, material.getCodigo());
            // Executando comando SQL
            prepared.executeUpdate();
            // Resultado
            System.out.println("Alteração do produto realizada com exito.");
            return true;

            // Tratamento de erro
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("Erro ao altera produto.");
            return false;
        }

    }

    public static Cliente[] consultar(Cliente cliente) {
        PreparedStatement preparedStatement;
        ResultSet resultset;
        int contador = 0;
        int nRegistros = 0;
        try {
            if (cliente.getCodigo() != 0) {
                preparedStatement = connection.prepareStatement("SELECT * FROM cliente "
                        + "WHERE codigo LIKE ? AND ativo=1");
                preparedStatement.setString(1, cliente.getCodigo() + "");
                resultset = preparedStatement.executeQuery();
            } else if (!cliente.getNome().equals("")) {
                preparedStatement = connection.prepareStatement("SELECT * FROM cliente "
                        + "WHERE nome LIKE ? AND ativo=1");
                preparedStatement.setString(1, "%" + cliente.getNome() + "%");
                resultset = preparedStatement.executeQuery();
            } else if (!cliente.getCpf().toString().equals("")) {
                preparedStatement = connection.prepareStatement("SELECT * FROM cliente "
                        + "WHERE cpf LIKE ? AND ativo=1");
                preparedStatement.setString(1, cliente.getCpf().toString() + "%");
                resultset = preparedStatement.executeQuery();
            } else if (cliente.getRg() != 0) {
                preparedStatement = connection.prepareStatement("SELECT * FROM cliente "
                        + "WHERE rg LIKE ? AND ativo=1");
                preparedStatement.setString(1, String.valueOf(cliente.getRg()) + "%");
                resultset = preparedStatement.executeQuery();
            } else {
                preparedStatement = connection.prepareStatement("SELECT * FROM cliente "
                        + "WHERE ativo=1");
                resultset = preparedStatement.executeQuery();

            }

            while (resultset.next()) {
                nRegistros = nRegistros + 1;
            }
            Cliente[] clienteList = new Cliente[nRegistros];

            resultset = preparedStatement.executeQuery();
            while (resultset.next()) {
                //Contador de cliente
                contador++;
                Cliente c = gerarClienteFromResultset(resultset);
                clienteList[contador - 1] = c;

            }
            return clienteList;

        } catch (SQLException e) {
            e.printStackTrace();
            Cliente[] clienteList = new Cliente[0];
            return clienteList;
        }
    }
    
    public static Material[] consultar(Material material) {
        PreparedStatement preparedStatement;
        ResultSet resultset;
        int contador = 0;
        int nRegistro = 0;
        try {
            if (material.getCodigo() != 0) {
                preparedStatement = connection.prepareStatement("SELECT * FROM produtos "
                        + "WHERE codigo=? AND ativo=1");
                preparedStatement.setInt(1, material.getCodigo());
                resultset = preparedStatement.executeQuery();
            } else if (!material.getNome().equals("")) {
                preparedStatement = connection.prepareStatement("SELECT * FROM "
                        + "produtos WHERE nome LIKE ? and ativo=1");
                preparedStatement.setString(1, "%" + material.getNome() + "%");
                resultset = preparedStatement.executeQuery();
            } else {
                preparedStatement = connection.prepareStatement("SELECT * FROM produtos "
                        + "WHERE ativo=1");
                resultset = preparedStatement.executeQuery();

            }

            while (resultset.next()) {
                nRegistro++;
            }
            Material[] produtoList = new Material[nRegistro];
            resultset.beforeFirst();
            while (resultset.next()) {
                contador++;
                produtoList[contador - 1] = gerarMaterialFromResultset(resultset);
            }
            return produtoList;
        } catch (SQLException e) {
            e.printStackTrace();
            Material[] produtoList = new Material[0];
            return produtoList;
        }
    }
    
    public static Cortina[] consultar(Cortina cortina){
        return new Cortina[0];
    }
    
    private static Cliente gerarClienteFromResultset(ResultSet resultset) {

        try {
            Cliente cliente = new Cliente();
            cliente.setCodigo((Integer) resultset.getObject(1));
            cliente.setNome((String) resultset.getObject(2));
            cliente.setSexo((String) resultset.getObject(3));
            CPF cpf = new CPF((String) resultset.getObject(4));
            cliente.setCpf(cpf);
            cliente.setRg((Integer) resultset.getObject(5));
            //Enderero do cliente
            String rua = (String) resultset.getObject(6);
            int n = (Integer) resultset.getObject(7);
            String bairro = (String) resultset.getObject(8);
            String cidade = (String) resultset.getObject(9);
            String complemento = (String) resultset.getObject(10);
            String uf = (String) resultset.getObject(11);
            String cep = (String) resultset.getObject(15);
            //
            Endereco endereco = new Endereco();
            endereco.setRua(rua);
            endereco.setNum(n);
            endereco.setBairro(bairro);
            endereco.setCidade(cidade);
            endereco.setComplemento(complemento);
            endereco.setUf(uf);
            endereco.setCep(cep);
            cliente.setEndereco(endereco);
            //
            cliente.setEmail((String) resultset.getObject(12));
            cliente.setTelefone((String) resultset.getObject(13));
            cliente.setCelular((String) resultset.getObject(14));
            cliente.setInformacoes((String) resultset.getObject(16));
            return cliente;
        } catch (SQLException e) {
            e.printStackTrace();

            Cliente cliente = new Cliente();
            return cliente;
        }
    }
    
    private static Material gerarMaterialFromResultset(ResultSet resultset) {
        try {
            Material material = new Material();
            material.setCodigo((Integer) resultset.getObject(1));
            material.setNome((String) resultset.getObject(2));
            material.setPreco((Double) resultset.getObject(3));
            material.setInformacao((String) resultset.getObject(4));
            return material;
        } catch (SQLException e) {
            e.printStackTrace();
            Material produto = new Material();
            return produto;

        }

    }
    
}
